import re
from bs4 import BeautifulSoup as bs
from telegraph import Telegraph, utils
from addHTMLanchore import add_html_links
from config import CHANNEL_PICTURE_URL, CHANNELS_NAME
from tidylib import tidy_document
from logger import logging


def __get_image_width(img_el):
    """Проверяет ширину HTML элемента img и возвращает ее числовое значение в пикселях"""
    try:
        width = img_el['width']
    except KeyError:
        try:
            width = img_el['style'].split('width:')[1]
        except Exception:
            return 0
    return int(width.split('px')[0])


def __get_main_image(soup) -> str:
    """Проверяет ширину всех изображений в новости и возвращает
    ссылку на первое подходящее, либо на заданное по умолчанию,
    если не нашлось подходящего"""
    images = [i['src']
              for i in soup.find_all('img') if __get_image_width(i) >= 200]
    if images:
        return images[0]
    else:
        return CHANNEL_PICTURE_URL


def make_telegraph_post(title: str, url: str, html: str) -> dict:
    """Формирует телеграф пост из HTML и отправляет его. Возвращает резельтат отправки"""
    telegraph = Telegraph()
    telegraph.create_account(short_name='16108')

    
    soup = bs(html, 'html.parser')
    
    html_spec = str(soup)
    html_spec = add_html_links(html_spec)
    document, _ = tidy_document(html_spec, options={'numeric-entities':1})
    soup = bs(document, 'html.parser')
    html_spec = str(soup.body)
    # Обработка исходного HTML. Удаление неподходящих для телеграф тегов и замена
    html_spec = re.sub('<\/*body>', '', html_spec)
    html_spec = re.sub('<\/h\d>', '</h1><br />', html_spec, flags=re.IGNORECASE)
    html_spec = re.sub('h\d[^>]*>', 'strong>', html_spec, flags=re.IGNORECASE)
    html_spec = re.sub('<\/*table[^>]*>', '', html_spec, flags=re.IGNORECASE)
    html_spec = re.sub('<\/*tbody>', '', html_spec, flags=re.IGNORECASE)
    html_spec = re.sub('div[^>]*>', 'p>', html_spec, flags=re.IGNORECASE)
    html_spec = re.sub('article[^>]*>', 'p>', html_spec, flags=re.IGNORECASE)
    html_spec = re.sub('<\/*span[^>]*>', '', html_spec, flags=re.IGNORECASE)
    html_spec = re.sub('<\/*td>', '', html_spec, flags=re.IGNORECASE)
    html_spec = re.sub('tr>', 'p>', html_spec, flags=re.IGNORECASE)
    html_spec = re.sub('<\/*font[^>]*>', '', html_spec, flags=re.IGNORECASE)

    # Вставка заглавного изображения в верх поста и удаление его копии из основного HTML
    main_image = f'<img src="{__get_main_image(soup)}" alt="{title}">'
    html_spec = re.sub(
        f'<\/*img[^>]*{__get_main_image(soup)}[^>]*\/*>', '', html_spec, flags=re.IGNORECASE)
    html_spec = re.sub(
        f'<\/*img[^>]*thumbs_up.png[^>]*\/*>', '🙏', html_spec, flags=re.IGNORECASE)
    html_spec = main_image + html_spec

    # Специфическая функция для удаления лишнего текст в некоторых постах в канале 151
    html_spec = html_spec.replace('- >', '➡️ ')
    html_spec = html_spec.replace('- &gt;', '➡️ ')
    try:
        html_spec = '\n'.join(html_spec.split(
            'Мы в социальных сетях')[0].split('\n')[:-1])
    except Exception:
        pass
    
    try:
        html_spec = '\n'.join(html_spec.split(
            'Copyright ©')[0].split('\n')[:-1])
    except Exception:
        pass


    try:
        nodes = utils.html_to_nodes(html_spec)
    except Exception as e:
        logging.exception('Exception when html convert to node')
        if str(e).endswith("tag is not closed"):
            html = main_image
            for l in soup.body.get_text().split('\n'):
                if l.strip():
                    l = l.replace('- >', '➡️ ')
                    l = add_html_links(l)
                    html += "<p>" + l + "</p>\n"
        else:
            raise e

        return telegraph.create_page(
            title,
            author_name=CHANNELS_NAME,
            author_url=url,
            html_content=html
            )

    return telegraph.create_page(
        title,
        author_name=CHANNELS_NAME,
        author_url=url,
        content=nodes
    )
